/*
 * Copyright (c) 2025 Huawei Technologies Co., Ltd.
 * openFuyao is licensed under Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 *          http://license.coscl.org.cn/MulanPSL2
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PSL v2 for more details.
 */

package phaseutil

import (
	"fmt"
	"strings"
	"testing"

	"github.com/coreos/go-semver/semver"
	"sigs.k8s.io/cluster-api/util/version"
)

func compareVersions(oldVersion, newVersion string) (int, error) {
	oldv, err := version.ParseMajorMinorPatch(oldVersion)
	if err != nil {
		fmt.Printf("parse %v err %v\n", oldVersion, err)
		return 0, err
	}
	newv, err := version.ParseMajorMinorPatch(newVersion)
	if err != nil {
		fmt.Printf("parse %v err %v\n", newVersion, err)
		return 0, err
	}

	// step 2 compare cluster version upgrade
	return version.Compare(newv, oldv), nil
}

func TestVersionCompare(t *testing.T) {
	tests := []struct {
		name        string
		oldVersion  string
		newVersion  string
		expected    int
		shouldError bool
	}{
		{
			name:       "same versions",
			oldVersion: "v25.9.0",
			newVersion: "v25.9.0",
			expected:   0,
		},
		{
			name:       "old less than new - patch",
			oldVersion: "v25.9.0",
			newVersion: "v25.9.1",
			expected:   1,
		},
		{
			name:       "old greater than new - patch",
			oldVersion: "v25.9.1",
			newVersion: "v25.9.0",
			expected:   -1,
		},
		{
			name:        "version is illegal",
			oldVersion:  "v25.09",
			newVersion:  "v25.9",
			expected:    1,
			shouldError: true,
		},
	}
	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			result, err := compareVersions(tt.oldVersion, tt.newVersion)
			if err != nil {
				if !tt.shouldError {
					t.Errorf("compareVersions() error = %v, wantErr %v", err, tt.shouldError)
				}
			} else {
				if result != tt.expected {
					t.Errorf("compareVersions(%s, %s) = %d, expected %d",
						tt.oldVersion, tt.newVersion, result, tt.expected)
				}
			}
		})
	}
}

func isPatchVersion(version string) bool {
	cleanVersion := strings.TrimPrefix(version, "v")

	v, err := semver.NewVersion(cleanVersion)
	if err != nil {
		return false
	}

	return v.Patch > 0 && v.PreRelease == ""
}

func TestPatchVersion(t *testing.T) {
	tests := []struct {
		name    string
		version string
		isPatch bool
	}{
		{
			name:    "not patch case 1",
			version: "v25.09.0",
			isPatch: false,
		},
		{
			name:    "not patch case 2",
			version: "v25.9",
			isPatch: false,
		},
		{
			name:    "not patch case 3",
			version: "v25.09.1.rc",
			isPatch: false,
		},
		{
			name:    "patch case 1",
			version: "v25.09.1",
			isPatch: true,
		},
		{
			name:    "patch case 2",
			version: "v25.9.2",
			isPatch: true,
		},
	}
	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			isPatch := isPatchVersion(tt.version)
			if isPatch != tt.isPatch {
				t.Errorf("version %v should %v but %v", tt.version, tt.isPatch, isPatch)
			}
		})
	}
}
